package cn.hls.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

import cn.hls.constant.security.PermissionSegment;

/**
 * @fileName: ACL.java
 * @package: com.bangni.entity
 * @Description: ACL实体类
 * @author: yinghui.zhang
 * @email: uuhui@163.com
 * @date: 2015-4-7
 */

@Entity
@Table(name = "T_ACL")
@DynamicInsert
@DynamicUpdate
public class ACL extends BaseEntity {

	private static final long serialVersionUID = 1L;
	/**
	 * 授权状态：不确定 
	 */
	public static final int ACL_NEUTRAL = -1;
	/**
	 * 授权状态：不允许
	 */
	public static final int ACL_NO = 0;
	/**授权状态：允许**/
	public static final int ACL_YES = 1;
	/** 定义主体类型为角色变量**/
	public static final int TYPE_ROLE = 1;
	/** 定义主体类型为用户变量**/
	public static final int TYPE_USER = 2;
	/** 定义主体类型为机构变更(考虑不同区域下的使用情况)**/
	public static final int TYPE_ORG = 3;
	// 主体类型（用户和角色 1-角色 2－用户）
	private int principalType;
	// 主体标识 用户Id或角色Id及机构编号
	/**
	 * 
	 */
	private Long principalId;
	// 模块编号
	private Long moduleId;
	// 授权状态
	private int aclState;
	// 扩展的授权状态
	private int aclExtState;
	// 授权状态的掩码
	private int aclTriState;

	@Column(name = "principal_Type",length=1, columnDefinition = "CHAR default 1")
	public int getPrincipalType() {
		return principalType;
	}

	public void setPrincipalType(int principalType) {
		this.principalType = principalType;
	}

	@Column(name = "principal_Id" )
	public Long getPrincipalId() {
		return principalId;
	}

	public void setPrincipalId(Long principalId) {
		this.principalId = principalId;
	}

	@Column(name = "module_id")
	public Long getModuleId() {
		return moduleId;
	}

	public void setModuleId(Long moduleId) {
		this.moduleId = moduleId;
	}

	@Column(name = "ACL_STATE", length = 8)
	public int getAclState() {
		return aclState;
	}

	public void setAclState(int aclState) {
		this.aclState = aclState;
	}

	@Column(name = "ACL_EXT_STATE")
	public int getAclExtState() {
		return aclExtState;
	}

	public void setAclExtState(int aclExtState) {
		this.aclExtState = aclExtState;
	}

	@Column(name = "ACL_TRI_STATE")
	public int getAclTriState() {
		return aclTriState;
	}

	public void setAclTriState(int aclTriState) {
		this.aclTriState = aclTriState;
	}

	/**
	 * acl实例跟主体和资源关联<br>
	 * 针对此实例进行授权，某种操作是否允许<br>
	 * @param permission
	 *            只可取0、1、2、3 CRUD
	 * @param yes
	 *            true表示允许，false表示不允许
	 */
	public void setPermission(int permission, boolean yes) {
		int temp = 1;
		temp = temp << permission;
		if (yes) {
			aclState |= temp;
		} else {
			aclState &= ~temp;
		}
	}

	/**
	 * acl实例跟主体和资源关联<br>
	 * 针对此实例进行授权扩展，某种操作是否允许<br>
	 * @param permission
	 *            只可取0、1、2、3 CRUD
	 * @param yes
	 *            true表示允许，false表示不允许
	 */
	public void setExtPermission(int permission, boolean yes) {
		int temp = 1;
		temp <<= permission;
		if (yes)
			this.aclExtState |= temp;
		else
			this.aclExtState &= (temp ^ 0xFFFFFFFF);
	}

	private int[] getPermissionGroup(int permission) {
		for (int i = 0; i < PermissionSegment.C_GROUP.length; i++) {
			if (PermissionSegment.C_GROUP[i] == permission) {
				return PermissionSegment.C_GROUP;
			}
		}

		for (int i = 0; i < PermissionSegment.R_GROUP.length; i++) {
			if (PermissionSegment.R_GROUP[i] == permission) {
				return PermissionSegment.R_GROUP;
			}
		}

		for (int i = 0; i < PermissionSegment.U_GROUP.length; i++) {
			if (PermissionSegment.U_GROUP[i] == permission) {
				return PermissionSegment.U_GROUP;
			}
		}

		for (int i = 0; i < PermissionSegment.D_GROUP.length; i++) {
			if (PermissionSegment.D_GROUP[i] == permission) {
				return PermissionSegment.D_GROUP;
			}
		}
		return null;
	}

	
	private int getBitPermission(int permission) {
		if (this.aclTriState == -1) {
			return ACL_NEUTRAL;  
		}

		int temp = 1;
		temp <<= permission;
		temp &= this.aclState;
		if (temp != 0) {
			 return ACL_YES;  
		}
		return ACL_NO;  
	}

	private int getExtBitPermission(int permission) {
		if (this.aclTriState == -1) {
			return ACL_NEUTRAL;  
		}

		int temp = 1;
		temp <<= permission;
		temp &= this.aclExtState;
		if (temp != 0) {
			 return ACL_YES;  
		}
		return ACL_NO;
	}

	/** 
     * 获得ACL授权 
     * @param permission C/R/U/D授权 
     * @return 授权标识，允许/不允许/不确定 
     */  
	public int getPermission(int permission) {
		if (this.aclTriState == -1) {
			return ACL_NEUTRAL;
		}
		int isPermission = 0;
		int[] permissionGroup = getPermissionGroup(permission);
		for (int i = permissionGroup.length - 1; i >= 0; i--) {
			if ((permissionGroup[i] <= permission)
					&& (getBitPermission(permissionGroup[i]) == 1)) {
				isPermission = 1;
				break;
			}

		}

		return isPermission;
	}

	public int getExtPermission(int permission) {
		if (this.aclTriState == -1) {
			return ACL_NEUTRAL;
		}

		return getExtBitPermission(permission);
	}
	
	/** 
     * 设置本授权是否是继承的 
     * @param yes true表示继承，false表示不继承 
     */  
	public void setExtends(boolean yes) {
		if (yes)
			this.aclTriState = -1;
		else
			this.aclTriState = 0;
	}

}
